#pragma once

#include "QuotaMap.h"
#include "DataBase.h"
#include "ITableCache.h"
#include <vector>
#include <set>

namespace qb{
	namespace ht{
		class TableFile;
		class KeyRecordIdMap;
		class KeyRecordIdHashMap;
		class BatchWriteCache;
		class NewKeyIdMap;
		class IKeyIdMap{
		public:
			virtual ~IKeyIdMap(){}
			virtual void remove(const char* szKey) = 0;
			virtual void insert(const char* szKey, int len, int rid) = 0;
			virtual int find(const char* szKey) = 0;
			virtual int GetMemoryBytes()const = 0;
            virtual void GetAllRecord(std::vector<unsigned int>& records){}
			virtual int GetCount()const = 0;
			virtual void Expand(int capcity, double keylen){}
			virtual bool Flush(){ return false; }
		};
		class TableCache : public ITableCache{
		public:
			typedef std::set<RecordId> RecordIdSet;
			//typedef KeyRecordIdHashMap KeyIdMap;
			//typedef NewKeyIdMap KeyIdMap;
			class KeyLenStat{
				double		m_sum_length;
				int			m_count;
			public:
				KeyLenStat() :m_count(0), m_sum_length(0.0){}
				bool IsFull()const{ return m_count >= 100; }
				void Add(int length){ m_count++; m_sum_length += length; }
				double GetLength()const{ return m_count <= 0 ? 1 : (m_sum_length / m_count); }
			};
		protected:
			TableFile*		m_file;				// 拥有，缓存文件
			int				m_record_length;	// 单条记录的长度
			int				m_record_count;		// 总的记录个数
			RecordIdSet		m_delete_map;		// 已经删除的记录号
			KeyLenStat		m_keylen_stat;		// 键值长度统计
			QuotaMap		m_quotamap;			// 限额缓存表
			IKeyIdMap*		m_key_recordmap;	// key-->RecordId
			BatchWriteCache*	m_batch_cache;
			char*			m_swap_record;		// 临时交换出来的记录所保持的内存
			
			int				m_write_count;		// 写入次数
			int				m_swap_count;		// 交换次数
			int				m_viewsize, m_increase_size;
			bool			m_temp_file;
			bool			m_use_quotamap;
			kDataType		m_data_type;		// 关键列的数据类型
			int				m_key_bytes;		// 关键列的字节大小
			int				m_head_size;		// 映射文件的文件头大小
			std::string		m_name;				// 当前映射文件名称
			std::string		m_tag;				// 标签
		public:
			TableCache(int recordSize,int headSize, kDataType type, int bytes);
			~TableCache();
			IKeyIdMap* CreateKeyMap(kDataType type, int bytes);
			virtual void SetTempFile(bool temp){ m_temp_file = temp; }
			virtual void SetViewSize(int view){ m_viewsize = view; }
			virtual void SetIncreaseSize(int increase){ m_increase_size = increase; }
			int GetRecordCount()const{ return m_record_count; }
			int GetRecordLength()const{ return m_record_length; }
			bool Read(RecordId rid, char* record, int size);
			RecordId GetRecordId(const char* key);
			RecordId Write(RecordId rid, const void* record, int size, const char* key,bool direct=false);
			int GetMaxRecordId()const;
			TableFile* GetFile();
			TableFile* RecreateFile();
			virtual const std::string& GetName(){ return m_name; }
			virtual void SetName(const std::string& fullFileName);
			virtual void SetTag(const std::string& tag){ m_tag = tag; }

			void SetQuotaListener(QuotaMap::Listener* listener);
			virtual void SetCapcity(int capcity);
			virtual void Flush();

			virtual int GetHeadSize(){ return m_head_size; };
			virtual bool ReadHead(char*buf, int size);
			virtual bool WriteHead(const char*buf, int size,int count);
			
            virtual void GetAllRecord(std::vector<unsigned int>& records)override;
			virtual void BuildKeyMap(int count, int offset,int flagOffset=-1);
			virtual bool RemoveKey(const char* key);
			


			int GetMemoryBytes()const;
			int GetKeyBytes()const{ return m_key_bytes; }
			int GetSwapCount()const{ return m_swap_count; }
			int GetWriteCount()const{ return m_write_count; }
			int GetQuotaCapcity()const{ return m_quotamap.GetCapcity(); }
			int GetQuotaLength()const{ return m_quotamap.GetSlotLength(); }
			static void test();
		protected:
			TableFile* CreateTableFile(bool reset);
		};
	}//namespace ht
}//namespace qb
